﻿using System.Linq;
using CID.Domain.Operations;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Operations
{
    [TestFixture]
    class ServerRolePersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(ServerRole expected, ServerRole actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            CollectionAssert.AreEquivalent(expected.Assignments.Select(x => x.Id), actual.Assignments.Select(x => x.Id));
            CollectionAssert.AreEquivalent(expected.Components.Select(x => x.Id), actual.Components.Select(x => x.Id));
        }

        [Test]
        public void SaveNewServerRole_ServerRoleShouldBeSaved()
        {
            var session = OpenSession();
            var newServerRole = DataProvider.CreateServerRole();
            session.SaveOrUpdate(newServerRole);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newServerRole.Id);
            session = OpenSession();
            var retrievedServerRole = session.Get<ServerRole>(newServerRole.Id);
            AssertAreEqual(newServerRole, retrievedServerRole);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedServerRole_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newServerRole = DataProvider.CreateServerRole();
            session.SaveOrUpdate(newServerRole);
            CleanSession(session);

            session = OpenSession();
            var modifiedServerRole = session.Get<ServerRole>(newServerRole.Id);
            AssertAreEqual(newServerRole, modifiedServerRole); //Necessary to load lazy collections before the session is wiped out
            modifiedServerRole.ModifyProperty(x => x.Name);
            modifiedServerRole.ModifyProperty(x => x.Description);
            var component = Development.DataProvider.GetComponent(session, DevelopmentData.Component1);
            var environment = DataProvider.GetEnvironment(session, OperationsData.Environment1);
            var server = DataProvider.GetServer(session, OperationsData.Server1);
            modifiedServerRole.AddComponent(component);
            server.Assign(environment, modifiedServerRole);
            modifiedServerRole.ModifyProperty(x => x.Enabled);
            session.SaveOrUpdate(modifiedServerRole);
            session.SaveOrUpdate(component);
            CleanSession(session);

            session = OpenSession();
            var retrievedServerRole = session.Get<ServerRole>(newServerRole.Id);
            AssertAreEqual(modifiedServerRole, retrievedServerRole);
            CleanSession(session);
        }

        [Test]
        public void DeleteServerRole_ServerRoleShouldBeDeleted()
        {
            var session = OpenSession();
            var newServerRole1 = DataProvider.CreateServerRole();
            var newServerRole2 = DataProvider.CreateServerRole();
            session.SaveOrUpdate(newServerRole1);
            session.SaveOrUpdate(newServerRole2);
            CleanSession(session);

            session = OpenSession();
            var retrievedServerRole1 = session.Get<ServerRole>(newServerRole1.Id);
            session.Delete(retrievedServerRole1);
            CleanSession(session);
        
            session = OpenSession();
            retrievedServerRole1 = session.Get<ServerRole>(newServerRole1.Id);
            var retrievedServerRole2 = session.Get<ServerRole>(newServerRole2.Id);
            Assert.IsNull(retrievedServerRole1);
            Assert.IsNotNull(retrievedServerRole2);
            CleanSession(session);
        }
    }
}
